From: Keir Fraser Date: Mon, 1 Jun 2009 13:07:46 +0000 (+0100) Subject: tmem: fix corner case crash on forcible domain destruction X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~13840 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=f475395032ee456f85242bd14fe59061b6d48b3f;p=xen.git tmem: fix corner case crash on forcible domain destruction When a tmem-enabled domain is destroyed, if the domain was using a persistent pool, the domain destruction process to scrubs page races tmem's attempts to gracefully dismantle data structures. Move tmem_destroy earlier in the domain destruction process. Signed-off-by: Dan Magenheimer Signed-off-by: Keir Fraser --- diff --git a/xen/common/domain.c b/xen/common/domain.c index 50dd43655d..0bce563331 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -402,6 +402,8 @@ int domain_kill(struct domain *d) spin_barrier(&d->domain_lock); evtchn_destroy(d); gnttab_release_mappings(d); + tmem_destroy(d->tmem); + d->tmem = NULL; /* fallthrough */ case DOMDYING_dying: rc = domain_relinquish_resources(d); @@ -583,9 +585,6 @@ static void complete_domain_destroy(struct rcu_head *head) grant_table_destroy(d); - if ( d->tmem != NULL ) - tmem_destroy(d->tmem); - arch_domain_destroy(d); rangeset_domain_destroy(d); diff --git a/xen/common/tmem.c b/xen/common/tmem.c index 0ab7b55c86..e40bc64505 100644 --- a/xen/common/tmem.c +++ b/xen/common/tmem.c @@ -867,7 +867,6 @@ static void client_free(client_t *client) { list_del(&client->client_list); tmh_client_destroy(client->tmh); - tmh_set_current_client(NULL); tmem_free(client,sizeof(client_t),NULL); } @@ -1992,20 +1991,17 @@ EXPORT void tmem_destroy(void *v) { client_t *client = (client_t *)v; + if ( client == NULL ) + return; + if ( tmh_lock_all ) spin_lock(&tmem_spinlock); else write_lock(&tmem_rwlock); - if ( client == NULL ) - printk("tmem: can't destroy tmem pools for %s=%d\n", - cli_id_str,client->cli_id); - else - { - printk("tmem: flushing tmem pools for %s=%d\n", - cli_id_str,client->cli_id); - client_flush(client,1); - } + printk("tmem: flushing tmem pools for %s=%d\n", + cli_id_str, client->cli_id); + client_flush(client, 1); if ( tmh_lock_all ) spin_unlock(&tmem_spinlock);